/**
 *******************************************************************************
 * \brief   CAS EBX Project Work "Kaffeemaschine"
 *
 * \file    cup.c
 * \version 1.0
 * \date    30.06.2010
 * \author  Baehler Thomas, Liechti Beat, Sauter Marc
 * \author  Vuksic Valentina, Zbinden Rene
 *
 * \remark  Last Modifications:
 * \remark  V1.0, 30.06.2010   Initial release
 *******************************************************************************
 **/

/*
 *******************************************************************************
 * Definitions
 *******************************************************************************
 */
/** \brief The niveau sensor delivers a value of 1, if there is an empty cup
 * present.*/
#define EMPTYCUP 1


/*
 *******************************************************************************
 * Imports
 *******************************************************************************
 */
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <syslog.h>
#include <unistd.h>

#include "coffee2.h"
#include "channel.h"
#include "pool.h"
#include "device.h"

/*
 *******************************************************************************
 * Local Variables
c *******************************************************************************
 */
static tChannel *c10, *c11; /*, *c36;*/
static tPool *p3;
static tDevice *d36;
static int timeExpired;

/*
 *******************************************************************************
 * Local Function Declaration
 *******************************************************************************
 */
static void sigtermHandler(int signal);
static void setTimeExpired(int signal);


/**
 *******************************************************************************
 * sigtermHandler
 *
 * \brief handle SIGTERM signal, close all pools and channels and exit
<<<<<<< local
=======
 *
 * \return void
>>>>>>> other
 *
 *******************************************************************************
 **/
static void sigtermHandler(int signal) {
	syslog(LOG_INFO, "SIGTERM reveiced, stopping ...");
	/* close channels and pools */
	closeChannel(c10);
	closeChannel(c11);
	//closeChannel(c36);
	closeDevice(d36);
	closePool(p3);
	/* close syslog */
	closelog();
	/* close and remove the runfile */
	exit(EXIT_SUCCESS);
}


/**
 *******************************************************************************
 * setTimeExpired
 *
 * \brief handle SIGALRM signal, set timeExpired
<<<<<<< local
=======
 *
 * \return void
>>>>>>> other
 *
 *******************************************************************************
 **/
static void setTimeExpired(int signal) {
	timeExpired = 1;
	return;
}


/**
 *******************************************************************************
 * mainCup
 *
<<<<<<< local
 * * \brief Activity: "Tasse"
=======
 * \brief Aktivität: "Tasse"
 *
 * \return pid
>>>>>>> other
 *
 *******************************************************************************
 **/
pid_t mainCup(){
	pid_t pid;
	sigset_t sigmask;
	struct sigaction sigtermAction;
	enum e_errors error = NO_ERROR;
	int order = 0;
	int niveau = 0;

	pid = fork();
	if (pid == 0) {
		/* syslog */
		openlog("coffee-cup", LOG_PID, LOG_DAEMON);
		/* block all signals other than SIGTERM */
		sigemptyset(&sigmask);
		sigaddset(&sigmask, SIGTERM);
		sigtermAction.sa_handler = sigtermHandler;
		sigtermAction.sa_mask = sigmask;
		if (sigaction(SIGTERM, &sigtermAction, NULL) == -1){
			syslog(LOG_ERR, "unable to setup signal handling!");
		}
		/* register alarm function */
		if (signal(SIGALRM, setTimeExpired) == SIG_ERR) {
			syslog(LOG_ERR, "can't register SIGALRM!");
		}
		/* open channels and pools */
		c10 = openChannelRead("C10", sizeof(int));  /* read from "Tasse" */
		c11 = openChannelWrite("C11", sizeof(int)); /* write to "Wasser" */
		//c36 = openChannelRead("C36", sizeof(int));  /* read from "Niveau" */
		d36 = openDeviceRead("/dev/c2nvaumtr");
		p3 = openPool("P3", sizeof(error));         /* "Error" */

		while (1) {
			if (readChannel(c10, &order) > 0) {
				syslog(LOG_INFO, "order from C10 received");
				timeExpired = 0;
				alarm(WAIT_FOR_CUP_TIMEOUT);
				//readChannel(c36, &niveau);
				readDevice(d36, &niveau);
				while (niveau != EMPTYCUP && timeExpired == 0) {
					usleep(500);
					//readChannel(c36, &niveau);
					readDevice(d36, &niveau);
				}
				alarm(0);
				/* we've got an empty cup */
				if (timeExpired == 0) {
					syslog(LOG_INFO, "sending order to C11");
					writeChannel(c11, &order);
				} else {
					syslog(LOG_ERR, "no empty cup");
					error = NO_CUP;
					writeToPool(p3, &error);
				}
			}
			usleep(500);
		}
	}
	return pid;
}


